var Svm = function (options) {
    this.init(options);
};

Svm.prototype.init = function (options) {
    this.$options = options;
    this.$el = document.querySelector(options.el);
    this.$data = options.data;
    this.$binding = {};
    this.$methods = typeof options.methods === 'undefined' ? {} : options.methods;
    this.observe(this.$data);
    this.compile(this.$el);
};

Svm.prototype.observe = function (obj) {
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            this.$binding[key] = {
                _directives: []
            };
            var value = obj[key];
        }
        if (typeof value === 'object') {
            this.observe(value);
        }
        let binding = this.$binding[key];
        Object.defineProperty(this.$data, key, {
            enumerable: true,
            configurable: true,
            get: function () {
                return value;
            },
            set: function (val) {
                if (val !== value) {
                    value = val;
                    binding._directives.forEach(function (item) {
                        item.update();
                    });
                }
            }
        });
    }
};

Svm.prototype.compile = function (rootNode) {
    var $this = this;
    var nodes = rootNode.children;
    // 遍历传入的dom
    for (var i = 0; i < nodes.length; i++) {
        var node = nodes[i];
        //递归遍历
        if (node.children.length) {
            this.compile(node)
        }
        //对元素上的属性做判断
        //s-click
        if (node.hasAttribute('s-click')) {
            node.onclick = (function () {
                let attrVal = node.getAttribute('s-click');
                return $this.$methods[attrVal].bind($this.$data)//返回对应方法绑定到对应的node上
            })()
        }
        //s-model
        if (node.hasAttribute('s-model') && (node.tagName === 'INPUT' || node.tagName === 'TEXTAREA')) {
            node.addEventListener('input', (function (i) {
                let attrVal = node.getAttribute('s-model');
                $this.$binding[attrVal]._directives.push(new Watcher(
                    'input',
                    node,
                    $this,
                    attrVal,
                    'value'
                ));
                return function (e) {
                    //修改data数据
                    if (e && e.target && e.target.value) {
                        $this.$data[attrVal] = e.target.value;
                    }
                    else {
                        var type = typeof _this.$data[attrVal];
                        if (type === 'number')
                            $this.$data[attrVal] = 0;
                        else
                            $this.$data[attrVal] = '';
                    }
                };
            })(i));
        }
        //s-bind
        if (node.hasAttribute('s-bind')) {
            let attrVal = node.getAttribute('s-bind');
            $this.$binding[attrVal]._directives.push(new Watcher(
                'text',
                node,
                $this,
                attrVal,
                'innerHTML'
            ))
        }
    }
};

/**
 * [Watcher 监听数据更新DOM]
 * @param {[type]} name [指令名称]
 * @param {[type]} el   [指令对应的DOM元素]
 * @param {[type]} vm   [所属的Svm实例]
 * @param {[type]} exp  [data中的属性]
 * @param {[type]} attr [绑定的属性值]
 */
function Watcher(name, el, vm, exp, attr) {
    this.name = name;
    this.el = el;
    this.vm = vm;
    this.exp = exp;
    this.attr = attr;
    this.update();
}

Watcher.prototype.update = function () {
    this.el[this.attr] = this.vm.$data[this.exp];
}